package swe.article;

import java.io.Serializable;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.management.RuntimeErrorException;

import swe.user.User;

public class Article implements Serializable {

	
	
	private static final long serialVersionUID = 1L;

	
	private User user;
	private String id;
	private String title = "empty car";
	private String description = "";
	private String image = "";
	private boolean isAuction = false;
	private Category category;
	private long created;
	private long endDatetime;
	private double startprice = 0;
	private Rating rating;
	private boolean ratingCommited;

	private List<ArticleBid> articleBidList = new ArrayList<ArticleBid>();
	
	SimpleDateFormat sdf = new SimpleDateFormat("dd. MMM yyyy, HH:mm");
	
	Article() {
		MessageDigest m;
		try {
			m = MessageDigest.getInstance("MD5");
			m.update(this.toString().getBytes(),0,this.toString().length());
			this.id = new BigInteger(1,m.digest()).toString(16);
			
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		this.created = System.currentTimeMillis();
		
	}
	
	/*
	 * von Servlet verwendet
	 */
	
	public Article(User user, String title, String description, String image, double startprice, Category c, boolean isAuction, int runningTime) {
		this();
		this.user = user;
		this.title = title;
		this.description = description;
		this.image = image;
		this.startprice = startprice;
		this.category = c;
		this.isAuction = isAuction;
		
		//this.endDatetime = System.currentTimeMillis()+(runningTime*86400000);
		//this.endDatetime = System.currentTimeMillis()+300000;
		this.endDatetime = System.currentTimeMillis()+runningTime;
		this.rating = null;
		this.ratingCommited = false;
	}
	
	Article(String title, String description, String image, double startprice) {
		this();
		this.title = title;
		this.description = description;
		this.image = image;
		this.startprice = startprice;
		this.category = Category.KLEINWAGEN;
		
		this.rating = null;
		this.ratingCommited = false;
	}
	

	public Article(User user, String title, String description, String image, double startprice) {
		this();
		this.user = user;
		this.title = title;
		this.description = description;
		this.image = image;
		this.startprice = startprice;
		this.category = Category.KLEINWAGEN;
		
		
		this.rating = null;
		this.ratingCommited = false;
		
	}
	
	public User getUser() {
		return this.user;
	}
	
	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Category getCategory() {
		return category;
	}
	
	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getImage() {
		if(image == null)
			return "http://placehold.it/300x240";
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public double getStartprice() {
		return startprice;
	}

	public void setStartprice(double startprice) {
		this.startprice = startprice;
	}
	
	public String getID() {
		return this.id;
	}

	public boolean getIsAuction() {
		return this.isAuction;
	}
	
	public String getShortenedDescription() {
		if(this.description.length() < 100) {
			return this.description;
		} else {
			return this.description.substring(0,100);
		}
	}
	
	public String getCreatedHuman() {
		return sdf.format(new Date(this.created));
	}
	
	public String getEndDatetimeHuman() {
		return sdf.format(new Date(this.endDatetime));
	}
	
	public boolean isActive() {
		if(this.isAuction && (this.getEnddatetime() > System.currentTimeMillis())) {
			return true;
		} else if (!this.isAuction && (this.articleBidList.size()<1 && (this.getEnddatetime() > System.currentTimeMillis()))){
			return true;
		}
		return false;
	}
	
	public long getEnddatetime() {
		return this.endDatetime;
	}
	
	
	public double getHighestBid() {
		double max = this.startprice;
		for(ArticleBid bid: articleBidList) {
			if(max < bid.getBidValue()) {
				max = bid.getBidValue();
			}
		}
		return max;
	}

	
	public void addBid(ArticleBid bid) {
		this.articleBidList.add(bid);
	}
	
	
	public List<ArticleBid> getBids() {
		return this.articleBidList;
	}
	
	public ArticleBid getLastBid() throws Exception {
		if(articleBidList.size() == 0) {
			throw new Exception("No bids");
		}
		
		return articleBidList.get(articleBidList.size() - 1);
	}
	
	
	public void setBought(User u) {
		this.articleBidList.add(new ArticleBid(this.startprice, u));
	}
	
	
	public void addRating(Double rating, User fromuser){
		
		System.out.println("ArticleClass addRating got called");
		
		if (!this.ratingCommited){
			System.out.printf("Rating existiert nicht GO");
			this.rating = new swe.article.Rating(rating, fromuser);
			this.ratingCommited = true;
		} else {
			System.out.printf("Rating existiert bereits, sollte nicht passieren. ICH ICH WEIS man sollte hier eine Exception werfen, bin im moment aber zu faul, mfg, Michi Strasser");
			
		}
	}
	
	public swe.article.Rating getRating(){
		return this.rating;
	}
	
	public Boolean isRated(){
		return this.ratingCommited;
	}
}
